﻿//
// Author: Ruxo Zheng (http://ruxozheng.spaces.live.com/)
//
// This file is distributed under CPOL 1.0 License (http://www.codeproject.com/info/cpol10.aspx).
//

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RZ.Web
{
    abstract class HtmlLexer
    {
        protected String content;
        protected Int32 cursor = 0;

        protected HtmlLexer(String content)
        {
            this.content = content;
        }

        public String Content
        {
            get { return this.content; }
        }

        public Int32 Cursor
        {
            get { return this.cursor; }
            set { this.cursor = value; }
        }

        public Boolean EOC
        {
            get { return this.cursor >= this.content.Length; }
        }

        #region Position save helper
        public Int32 BeginCheck()
        {
            return this.cursor;
        }

        public Boolean CommitCheck(bool commit, Int32 savedCursor)
        {
            if (!commit)
                this.cursor = savedCursor;
            return commit;
        }
        #endregion

        public String GetContent(Int32 begin)
        {
            return this.content.Substring(begin, this.cursor - begin);
        }

        protected Char L(Int32 offset)
        {
            return this.content[this.cursor + offset];
        }

        protected Int32 ValidContentLength
        {
            get { return this.content.Length - this.cursor; }
        }

        protected Char Read()
        {
            return this.content[this.cursor++];
        }

        protected Boolean MoveCursor(bool condition, Int32 step)
        {
            if (condition)
                this.cursor = Math.Min(this.content.Length, this.cursor + step);
            return condition;
        }

        protected Boolean CheckInsensitive(String text)
        {
            if (!ValidLength(text.Length))
                return false;

            return this.content.IndexOf(text, this.cursor, text.Length, StringComparison.InvariantCultureIgnoreCase) != -1;
        }

        protected Boolean ValidLength(Int32 requiredLength)
        {
            return !EOC && ValidContentLength >= requiredLength;
        }
    }
}
